#include "Network.h"
#include <errno.h>

namespace Network
{
	/*
	** Class Data
	*/
	Data::Data(SOCKET socket, SOCKADDR_IN* saddr, std::list<std::string>* list, std::list<Connection*>* cList)
		: socket(socket), saddr(saddr), list(list), cList(cList)
	{

	}

	Data::~Data()
	{

	}

	Data::Data(const Data& nd)
	{
		this->socket = nd.socket;
		this->saddr = nd.saddr;
		this->list = nd.list;
		this->cList = nd.cList;
	}

	const SOCKET&			Data::getSocket() const
	{
		return (socket);
	}

	SOCKADDR_IN*			Data::getSAddr() const
	{
		return (saddr);
	}

	std::list<std::string>*	Data::getList() const
	{
		return (list);
	}

	std::list<Connection*>*	Data::getCList() const
	{
		return (cList);
	}
	/* **************************** */





	/*
	** Class Recv
	*/
	Recv::Recv()
	{

	}

	Recv::~Recv()
	{

	}

	void	Recv::start(void* data)
	{
		this->_data = (Network::Data*)data;
#ifdef WIN32
		_t = CreateThread(NULL, 0, &Recv::loop, _data, 0, NULL);
#else
		pthread_create(&_t, NULL, &Recv::loop, (void*)_data);
#endif
	}

	RETVAL TTYPE	Recv::loop(functionParam arg)
	{
		Data*					data = (Data*)arg;
		SOCKADDR_IN*			saddr = data->getSAddr();
		int						bytesReceived;
		char					buffer[128];
		int						saddr_size = sizeof(*saddr);
		u_long					fromaddr;
		char*					clientAddr;

		while (1)
		{
			bytesReceived = recvfrom(data->getSocket(), buffer, 128, 0, (struct sockaddr *)saddr, &saddr_size);
			if (bytesReceived > 0)
			{
				fromaddr = saddr->sin_addr.s_addr;
				clientAddr = (gethostbyaddr((char *)&fromaddr, sizeof(fromaddr), AF_INET))->h_name;
				std::string msg = std::string(clientAddr) + " " + Utils::intToString(saddr->sin_port) + " " + Utils::intToString(bytesReceived) + " " + std::string(buffer);
				data->getList()->push_back(msg);
			}
			else
				std::cout << "Error. " << errno << std::endl;
		}
	}

	void	Recv::stop()
	{
#ifdef WIN32
		TerminateThread(_t, NULL);
#else
		pthread_cancel(_t);
#endif
	}
	/* **************************** */





	/*
	** Class Send
	*/
	Send::Send()
	{

	}

	Send::~Send()
	{

	}

	void	Send::start(void* data)
	{
		this->_data = (Network::Data*)data;
#ifdef WIN32
		_t = CreateThread(NULL, 0, &Send::loop, _data, 0, NULL);
#else
		pthread_create(&_t, NULL, &Send::loop, (void*)_data);
#endif
	}

	RETVAL TTYPE	Send::loop(functionParam arg)
	{
		Data* data = (Data*)arg;

		while (1)
		{

		}
	}

	void	Send::stop()
	{
#ifdef WIN32
		TerminateThread(_t, NULL);
#else
		pthread_cancel(_t);
#endif
	}
	/* **************************** */
};
